using System.Text.RegularExpressions;
using data.contracts;
using NUnit.Framework;

namespace generator.tests
{
    [TestFixture]
    public class InterfaceGeneratorTests
    {
        [Test]
        public void Generate_output_pin_on_interface_with_no_param() {
            var pinDef = InterfaceGenerator.GenerateEvent("MyOutput", "");
            Assert.IsTrue(Regex.Match(pinDef, @"event\s+Action\s+MyOutput").Success);
        }

        [Test]
        public void Generate_output_pin_on_interface_with_star_type() {
            var pinDef = InterfaceGenerator.GenerateEvent("MyOutput", "int*");
            Assert.IsTrue(Regex.Match(pinDef, @"event\s+Action<IEnumerable<int>>\s+MyOutput").Success);
        }

        [Test]
        public void Generate_input_pin_on_interface_with_no_param() {
            var pinDef = InterfaceGenerator.GenerateMethod("MyInput", "");
            Assert.IsTrue(Regex.Match(pinDef, @"void\s+MyInput\(\)").Success);
        }

        [Test]
        public void Generate_input_pin_on_interface_with_star_type() {
            var pinDef = InterfaceGenerator.GenerateMethod("MyInput", "string*");
            Assert.IsTrue(Regex.Match(pinDef, @"void\s+MyInput\(IEnumerable<string> message\)").Success);
        }

        [Test]
        public void Interface_for_part_without_dependencies() {
            var @interface = InterfaceGenerator.GenerateInterface(
                new Pin {Board = "M"},
                new[] {
                    new Wire("A", "T", "B") {
                        FromPin = new Pin {Board = "A", Name = "", Type = ""},
                        ToPin = new Pin {Board = "B", Name = "", Type = ""}
                    }
                },
                new Dependency[] {}
                );
            Assert.That(@interface, Is.EqualTo("public interface IM {\r\n}\r\n"));
        }

        [Test]
        public void Interface_for_part_with_one_dependency() {
            var @interface = InterfaceGenerator.GenerateInterface(
                new Pin {Board = "M"},
                new[] {
                    new Wire("A", "T", "B") {
                        FromPin = new Pin {Board = "A", Name = "", Type = ""},
                        ToPin = new Pin {Board = "B", Name = "", Type = ""}
                    }
                },
                new[] {new Dependency {Dependent = "M", Type = "TD"}}
                );
            Assert.That(@interface, Is.EqualTo("public interface IM : IDependsOn<TD> {\r\n}\r\n"));
        }

        [Test]
        public void Interface_for_part_with_multiple_dependencies() {
            var @interface = InterfaceGenerator.GenerateInterface(
                new Pin {Board = "M"},
                new[] {
                    new Wire("A", "T", "B") {
                        FromPin = new Pin {Board = "A", Name = "", Type = ""},
                        ToPin = new Pin {Board = "B", Name = "", Type = ""}
                    }
                },
                new[] {
                    new Dependency {Dependent = "M", Type = "T1"},
                    new Dependency {Dependent = "M", Type = "T2"},
                    new Dependency {Dependent = "M", Type = "T3"}
                }
                );
            Assert.That(@interface, Is.EqualTo("public interface IM : IDependsOn<T1>, IDependsOn<T2>, IDependsOn<T3> {\r\n}\r\n"));
        }

        [Test]
        public void Interface_for_part_with_multiple_dependencies_for_different_parts() {
            var @interface = InterfaceGenerator.GenerateInterface(
                new Pin {Board = "M"},
                new[] {
                    new Wire("A", "T", "B") {
                        FromPin = new Pin {Board = "A", Name = "", Type = ""},
                        ToPin = new Pin {Board = "B", Name = "", Type = ""}
                    }
                },
                new[] {
                    new Dependency {Dependent = "M", Type = "T1"},
                    new Dependency {Dependent = "N", Type = "T2"},
                    new Dependency {Dependent = "O", Type = "T3"}
                }
                );
            Assert.That(@interface, Is.EqualTo("public interface IM : IDependsOn<T1> {\r\n}\r\n"));
        }

        [Test]
        public void Interface_for_part_with_multiple_dependencies_only_for_other_parts() {
            var @interface = InterfaceGenerator.GenerateInterface(
                new Pin {Board = "M"},
                new[] {
                    new Wire("A", "T", "B") {
                        FromPin = new Pin {Board = "A", Name = "", Type = ""},
                        ToPin = new Pin {Board = "B", Name = "", Type = ""}
                    }
                },
                new[] {
                    new Dependency {Dependent = "X", Type = "T1"},
                    new Dependency {Dependent = "Y", Type = "T2"},
                    new Dependency {Dependent = "Z", Type = "T3"}
                }
                );
            Assert.That(@interface, Is.EqualTo("public interface IM {\r\n}\r\n"));
        }
    }
}